package com.hfzy.ihk.web.ivr.biz;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hfzy.ihk.common.facade.enums.call.CommitTo;
import com.hfzy.ihk.common.util.ValidateUtils;
import com.hfzy.ihk.common.util.date.DateUtils;
import com.hfzy.ihk.common.util.http.HttpClientUtils;
import com.hfzy.ihk.common.util.string.StringTools;
import com.hfzy.ihk.facade.ivr.enums.CallInSource;
import com.hfzy.ihk.facade.ivr.enums.MainCallTypeEnum;
import com.hfzy.ihk.facade.ivr.vo.CallInto;
import com.hfzy.ihk.web.ivr.constant.*;
import com.hfzy.ihk.web.ivr.context.EventSocketInitBean;
import com.hfzy.ihk.web.ivr.support.SelectShowNumSupport;
import com.hfzy.ihk.web.ivr.websocket.WebSocketUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Created by Administrator on 2019/5/24.
 */
@Component
public class CallIntoStartBiz {

    private static final Logger logger = LoggerFactory.getLogger(CallIntoStartBiz.class);

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    WebSocketUtils webSocketUtils;

    @Autowired
    NumBindingBiz numBindingBiz;

    @Autowired
    SelectShowNumSupport selectShowNum;

    @Autowired
    private EventSocketInitBean eslInitBean;


    public Map<String,Object> callInto(CallInto callInto)throws Exception{
        Map<String,Object> map = new HashMap<>();
        if(StringTools.isEmpty(callInto)||StringTools.isEmpty(callInto.getCallInSource())){
            logger.info("呼入来源为空------------------------data:{}", JSON.toJSONString(callInto));
            return map;
        }
        switch (callInto.getCallInSource()){
            case FREESWITCH:
                logger.info("freeswitch呼入----------data：{}", JSON.toJSONString(callInto));
                freeswitchCallInto(callInto);
                /*测试用的*/
                //String targetCallPhone = "010202295308413632446454";
                //eslInitBean.getClient().sendAsyncApiCommand("uuid_transfer", callInto.getSessionsId()+" "+targetCallPhone+" XML default");
                break;
            case DONGJIN:
                logger.info("东进呼入----------data：{}", JSON.toJSONString(callInto));
                dongjinCallInto(callInto);
                break;
            case ALIYUN:
                logger.info("阿里云呼入----------data：{}", JSON.toJSONString(callInto));
                map = aliyunCallInto(callInto);
                break;
            default:
                logger.info("呼入来源不存在----------data：{}", JSON.toJSONString(callInto));
        }
        return map;
    }

    /**
     * freeswitch 呼入转接
     * @param callInto
     */
    private void freeswitchCallInto(CallInto callInto) throws Exception{
        Map<String,String> redisSaveMap = new HashMap<>();
        String rediskey = RedisKey.CALL_HISTORY_RPIX+callInto.getSessionsId();
        String  nowDateStr = DateUtils.formatDate(new Date(), DateUtils.DATE_FORMAT_DATETIME_SSS);

        String mainCallPhone = callInto.getMainCallPhone();

        /*话术包id用于单呼语音分析*/
        Object tempJson = redisTemplate.opsForHash().get(RedisKey.createFsLastCallInfo(mainCallPhone),RedisKey.POPUP_WINDOW_ID);
        if(StringTools.isNotempty(tempJson)){
            JSONObject jsonObject = JSONObject.parseObject(tempJson.toString());
            if (!"0".equals(jsonObject.getString("packageId"))&&!"null".equals(jsonObject.getString("packageId"))){
                String callTaskId = "0";
                if(jsonObject.containsKey("callTaskId")){
                    callTaskId = jsonObject.getString("callTaskId");
                }
                redisSaveMap.put(RedisFields.PACKAGE_ID,jsonObject.getString("packageId"));
                redisSaveMap.put(RedisFields.CALL_TASK_ID,callTaskId);
                redisTemplate.opsForValue().set(RedisKey.ALIBABA_ASR+callInto.getSessionsId(), jsonObject.getString("packageId") + ":" + callTaskId, RedisTimeOut.CACHE_ONE_DAY, TimeUnit.SECONDS);
            }
        }

        /*获取呼出信息*/
        String callPhone;
        Map<String, String> numBindingMap = numBindingBiz.getLastCallUserNum("", mainCallPhone,CallInSource.FREESWITCH);
        if (numBindingMap == null||!numBindingMap.containsKey("targetCallPhone")||StringTools.isNullString(numBindingMap.get("targetCallPhone"))||"null".equals(numBindingMap.get("targetCallPhone"))) {//无呼出关系，无绑定数据，暂时不转接
            logger.info("freeswitch 呼入mainCallPhone:{}，被叫不存在或者没有呼出记录", mainCallPhone);

            addRedisSaveMap(redisSaveMap,callInto.getSessionsId(),"",mainCallPhone,"","-1",
                    "-1",nowDateStr,nowDateStr,CommitTo.ASR_FREESWITCH.getValue(),RedisKey.DEFAULT_CITY,
                    String.valueOf(MainCallTypeEnum.MAIN_CALL_PHONE_IS_CUSTOMER.getValue()),
                    Constants.IN_COME.toString(),Constants.TRUE);

            redisTemplate.opsForHash().putAll(rediskey,redisSaveMap);
            redisTemplate.expire(rediskey,RedisTimeOut.CACHE_ONE_DAY, TimeUnit.SECONDS);

            callPhone = PublicConfig.FS_CALL_INTO_TRANSFER_ASR_DIALPLAN;

            logger.info("呼入没有呼出记录进入单呼主叫号码：{}，拨号计划号码callPhone{}，sessionId:{}",mainCallPhone,callPhone,callInto.getSessionsId());

        }else{
            //获取主显号
            String showNum;
            if(StringTools.isNotNull(callInto.getShowNum())){
                logger.info("呼入进来有主显号，主叫号码：{}",callInto.getMainCallPhone());
                showNum = callInto.getShowNum();
            }else{
                showNum = selectShowNum.getCopShowNum(numBindingMap.get("cityId"));
            }

            String targetCallPhone = numBindingMap.get("targetCallPhone");//E1号码或手机号码

            addRedisSaveMap(redisSaveMap,callInto.getSessionsId(),showNum,mainCallPhone,targetCallPhone,numBindingMap.get("userId"),
                    numBindingMap.get("dataId"),nowDateStr,nowDateStr,CommitTo.FREESWITCH.getValue(),RedisKey.DEFAULT_CITY,
                    String.valueOf(MainCallTypeEnum.MAIN_CALL_PHONE_IS_CUSTOMER.getValue()),
                    Constants.IN_COME.toString(),Constants.TRUE);

            redisTemplate.opsForHash().putAll(rediskey,redisSaveMap);
            redisTemplate.expire(rediskey,RedisTimeOut.CACHE_ONE_DAY, TimeUnit.SECONDS);

            //获取呼出线路
            //getFreeswitchLine(targetCallPhone);
            //String targetCallPhone = "0113632446454";

            callPhone = PublicConfig.FS_CALL_INTO_TRANSFER_LIANTONG_DIALPLAN+showNum+targetCallPhone;

            logger.info("呼入主叫号码：{}，进入拨号被叫号码：{},主显号：{}，sessionId:{}",mainCallPhone,callPhone,showNum,callInto.getSessionsId());
        }

        if (!eslInitBean.getClient().canSend()) {
            logger.error("freeswitchl连接已经断开,呼入失败，呼入号码：{}",callInto.getMainCallPhone());
            //重新初始化客户端
            eslInitBean.initClient();
            return;
        }else{
            eslInitBean.addCall(callInto.getSessionsId());//将本次通话添加到由这个服务发起的通话map中
            eslInitBean.getClient().sendBackgroundApiCommand("uuid_transfer", callInto.getSessionsId()+" "+callPhone+" XML default");
        }

    }

    private Map<String,Object> aliyunCallInto(CallInto callInto)throws Exception{
        Map<String,Object> map = new HashMap<>();
        String targetCallPhone = null;
        Map<String,String> redisSaveMap = new HashMap<>();
        String  nowDateStr = DateUtils.formatDate(new Date(), DateUtils.DATE_FORMAT_DATETIME_SSS);
        String rediskey = RedisKey.CALL_HISTORY_RPIX+callInto.getSessionsId();

        String mainCallPhone = callInto.getMainCallPhone();

        String showNum = callInto.getShowNum();

        //控制回拨弹屏功能(默认true)
        showPopupWindow(showNum,mainCallPhone);

        /*客户呼入*/
        String callOutUseCallInKey = RedisKey.CALL_OUT_USE_CALL_IN_PRIX + showNum + ":" + mainCallPhone;
        Map<String,String> callOutUseCallInMap = redisTemplate.opsForHash().entries(callOutUseCallInKey);
        if(callOutUseCallInMap == null || callOutUseCallInMap.isEmpty()) { //直接呼入
            Map<String, String> numBindingMap = numBindingBiz.getLastCallUserNum(showNum, mainCallPhone,CallInSource.ALIYUN);

            if (numBindingMap == null) {
                logger.info("taobao callIn, numbinding not found: [mainCallPhone:{}, showNum:{}]", mainCallPhone, showNum);
                numBindingMap = new HashMap<>();
                numBindingMap.put("targetCallPhone", Constants.TAO_BAO_DEFAULT_TARGET_PHONE); //因为阿里云抽查设定为一个座机
                numBindingMap.put("userId", "-1");
                numBindingMap.put("dataId", "-1");
            }
            targetCallPhone = numBindingMap.get("targetCallPhone");//E1号码或手机号码
            String userId = numBindingMap.get("userId");

            //呼入到楼盘资讯部的，全部转入该号码
            //该部门老大ID：3854
            if("3854".equals(userId)){
                targetCallPhone="02038881855";
            }


            if (targetCallPhone == null || userId == null) {
                logger.info("taobao callIn, data not found: [mainCallPhone:{}, showNum:{}, targetCallPhone:{}, userId:{}]", mainCallPhone, showNum, targetCallPhone, userId);
            }

            logger.info("taobao callIn, transNum targetCallPhone:,messageId:{}" + targetCallPhone,callInto.getCallId());

            String key = RedisKey.createLastCallInfo(showNum,mainCallPhone);
            String cityId = StringTools.isEmpty(redisTemplate.opsForHash().get(key,RedisKey.LAST_CALL_INFO_CITY_ID))?"-1":redisTemplate.opsForHash().get(key, RedisKey.LAST_CALL_INFO_CITY_ID).toString();

            //cityId 目前无法区分是哪个城市打来
            addRedisSaveMap(redisSaveMap,callInto.getSessionsId(),showNum,mainCallPhone,targetCallPhone,userId,
                    numBindingMap.get("dataId"),nowDateStr,nowDateStr,CommitTo.ALIYUN.getValue(),cityId,
                    String.valueOf(MainCallTypeEnum.MAIN_CALL_PHONE_IS_CUSTOMER.getValue()),
                    Constants.IN_COME.toString(),Constants.TRUE);
        }else{ //app呼入
            //用完即删
            redisTemplate.delete(callOutUseCallInKey);

            targetCallPhone = callOutUseCallInMap.get(RedisFields.CALL_HISTORY_TARGET_CALL_PHONE);

            logger.info("taobao callOutUseCallIn, transNum targetCallPhone:{},showNUm:{},mainCallPhone:{}", targetCallPhone,showNum,mainCallPhone);

            addRedisSaveMap(redisSaveMap,callInto.getSessionsId(),showNum,mainCallPhone,targetCallPhone,callOutUseCallInMap.get(RedisFields.CREATE_USER_ID),
                    callOutUseCallInMap.get(RedisFields.CALL_HISTORY_DATA_ID),nowDateStr,nowDateStr,
                    callOutUseCallInMap.get(RedisFields.CALL_HISTORY_COMMIT_TO),callOutUseCallInMap.get(RedisFields.CALL_HISTORY_CITY),
                    callOutUseCallInMap.get(RedisFields.CALL_HISTORY_MAIN_CALL_TYPE),Constants.CALL_OUT_USE_CALL_IN.toString(),Constants.TRUE);

            addRedisSaveMap(redisSaveMap,callOutUseCallInMap.get(RedisFields.CALL_HISTORY_MACHINE_FROM),callOutUseCallInMap.get(RedisFields.CALL_HISTORY_WHERE_FROM),
                    callOutUseCallInMap.get(RedisFields.CALL_HISTORY_PAGE_FROM),callOutUseCallInMap.get(RedisFields.CALL_HISTORY_CUSTOMER_NAME),
                    nowDateStr);

        }
        redisSaveMap.put(RedisFields.CALL_HISTORY_MESSAGE_ID,callInto.getCallId());
        redisSaveMap.put(RedisFields.CALL_HISTORY_IMS, callInto.getCalledShowNum());
        redisSaveMap.put(RedisFields.PUBLIC_CALL_IN_FLAG,Constants.TRUE);//设置为呼入标志，不需推送状态
        /*保存呼叫数据,2天有效*/
        redisTemplate.opsForHash().putAll(rediskey,redisSaveMap);
        redisTemplate.expire(rediskey, RedisTimeOut.CACHE_ONE_DAY, TimeUnit.SECONDS);
        String createTimeStr = DateUtils.formatDate(new Date(), DateUtils.DATE_FORMAT_DATETIME_SSS);
        redisTemplate.opsForHash().put(RedisKey.COMMIT_SUCCESS_SESSIONID_AND_TIME,callInto.getSessionsId(),createTimeStr);


        if(!ValidateUtils.isMobile(targetCallPhone)){
            if (!targetCallPhone.startsWith("0")){
                targetCallPhone = "020"+targetCallPhone;
            }
        }
        map.put("targetCallPhone",targetCallPhone);
        return map;
    }

    private void dongjinCallInto(CallInto callInto)throws Exception{
        Map<String,String> redisSaveMap = new HashMap<>();
        String  nowDateStr = DateUtils.formatDate(new Date(), DateUtils.DATE_FORMAT_DATETIME_SSS);
        String rediskey = RedisKey.CALL_HISTORY_RPIX+callInto.getSessionsId();

        String mainCallPhone = callInto.getMainCallPhone();//38881773,07637355123,

        String showNum = callInto.getShowNum();//主显号--85700001
        if (!showNum.startsWith("0"))
            showNum = "020"+showNum;

        //控制回拨弹屏功能(默认true)
        showPopupWindow(showNum,mainCallPhone);

        String callOutUseCallInKey = RedisKey.CALL_OUT_USE_CALL_IN_PRIX + showNum + ":" + mainCallPhone;//主显+经纪号码--->为获取客户号码

        Map<String,String> callOutUseCallInMap = redisTemplate.opsForHash().entries(callOutUseCallInKey);

        if(callOutUseCallInMap == null || callOutUseCallInMap.isEmpty()) {//客户呼入->转接经纪

            Map<String, String> numBindingMap = numBindingBiz.getLastCallUserNum(showNum, mainCallPhone,CallInSource.DONGJIN);

            String targetCallPhone;
            String userId;
            if (numBindingMap == null) {//无呼出关系，无绑定数据，不转接
                logger.warn("income transNum not found: [mainCallPhone:{}, showNum:{}]", mainCallPhone, showNum);
                numBindingMap = new HashMap<>();
                numBindingMap.put("targetCallPhone", Constants.NULL_STR); //因为阿里云抽查设定为一个座机
                numBindingMap.put("userId", "-1");
                numBindingMap.put("dataId", "-1");
                targetCallPhone = Constants.NULL_STR;
                userId = "-1";
            }else{
                //E1号码或手机号码
                targetCallPhone = numBindingMap.get("targetCallPhone");
                userId = numBindingMap.get("userId");

                //呼入到楼盘资讯部的，全部转入该号码
                //该部门老大ID：3854
                if("3854".equals(userId)){
                    targetCallPhone="02038881855";
                }

                logger.debug("income transNum: [mainCallPhone:{}, showNum:{}, targetCallPhone:{}, userId:{}]", mainCallPhone, showNum, targetCallPhone, userId);

                //转接呼入
                numBindingBiz.transNum(callInto.getSessionsId(), mainCallPhone, numBindingMap.get("targetCallPhone"), showNum, callInto.getvPId());

                redisSaveMap.put(RedisFields.CALL_HISTORY_WHERE_FROM, "phone".equals(numBindingMap.get("phoneType")) ? "0" : "1");
            }

            //city 目前只有广州使用E1线路，所以呼入全是广州的分行，这里city固定1
            addRedisSaveMap(redisSaveMap,callInto.getSessionsId(),showNum,mainCallPhone,targetCallPhone,userId,
                    numBindingMap.get("dataId"),nowDateStr,callInto.getStateTime(),CommitTo.DONG_JIN.getValue(),
                    "1",String.valueOf(MainCallTypeEnum.MAIN_CALL_PHONE_IS_CUSTOMER.getValue()),
                    Constants.IN_COME.toString(),Constants.TRUE);

        }else {//经纪人在app呼主显来实现呼出功能（经纪呼入->转接客户）

            String callOutTargetCallPhone = callOutUseCallInMap.get(RedisFields.CALL_HISTORY_TARGET_CALL_PHONE);

            logger.debug("dongjin transNum callOutTargetCallPhone:{},showNUm:{},mainCallPhone:{}", callOutTargetCallPhone,showNum,mainCallPhone);
            //转接呼入

            try {
                numBindingBiz.transNum(callInto.getSessionsId(), mainCallPhone, callOutTargetCallPhone, showNum, callInto.getvPId());
            } finally {
                //用完即删
                redisTemplate.delete(callOutUseCallInKey);
            }

            addRedisSaveMap(redisSaveMap,callInto.getSessionsId(),showNum,mainCallPhone,callOutTargetCallPhone,callOutUseCallInMap.get(RedisFields.CREATE_USER_ID),
                    callOutUseCallInMap.get(RedisFields.CALL_HISTORY_DATA_ID),nowDateStr,callInto.getStateTime(),
                    CommitTo.DONG_JIN.getValue(),callOutUseCallInMap.get(RedisFields.CALL_HISTORY_CITY),
                    callOutUseCallInMap.get(RedisFields.CALL_HISTORY_MAIN_CALL_TYPE),Constants.CALL_OUT_USE_CALL_IN.toString(),Constants.TRUE);

            addRedisSaveMap(redisSaveMap,callOutUseCallInMap.get(RedisFields.CALL_HISTORY_MACHINE_FROM),callOutUseCallInMap.get(RedisFields.CALL_HISTORY_WHERE_FROM),
                    callOutUseCallInMap.get(RedisFields.CALL_HISTORY_PAGE_FROM),callOutUseCallInMap.get(RedisFields.CALL_HISTORY_CUSTOMER_NAME),
                    callInto.getStateTime());

        }

        redisTemplate.opsForHash().putAll(rediskey,redisSaveMap);
        redisTemplate.expire(rediskey,RedisTimeOut.CACHE_ONE_DAY, TimeUnit.SECONDS);

    }

    /**
     * 外呼弹屏
     * @param showNum
     * @param mainCallPhone
     */
    private void showPopupWindow(String showNum,String mainCallPhone){
        //如果不是手机，且没有区号，默认加区号为020
        if(!ValidateUtils.isMobile(mainCallPhone)){
            if (!mainCallPhone.startsWith("0")){
                mainCallPhone = "020"+mainCallPhone;
            }
        }

        if(PublicConfig.SHOW_POPUP_WINDOW){//控制回拨弹屏功能(默认true)
            //*****************返回弹屏数据****************//
            try {
                String key = RedisKey.createLastCallInfo(showNum,mainCallPhone);
                Object zyId = redisTemplate.opsForHash().get(key,RedisKey.LAST_CALL_INFO_USER_ID);
                Object content = redisTemplate.opsForHash().get(key,RedisKey.POPUP_WINDOW_ID);
                logger.info("------------showWindow----------[zyId:{},content:{}]",zyId,content);
                if(StringTools.isNotempty(zyId) && StringTools.isNotempty(content)){
                    boolean isFlag = webSocketUtils.isFlagWebSocketChromePlugin(zyId.toString());
                    if(isFlag){
                        final String mainCallPhoneFinal = mainCallPhone;
                        new Thread(){
                            @Override
                            public void run() {
                                try {
                                    String contentFinal = content.toString();
                                    if(PublicConfig.POPUP_PHONE.contains(mainCallPhoneFinal)){//指定客户电话回拨弹屏信息
                                        Object count = redisTemplate.opsForHash().get(RedisKey.CUSTOMER_CALL_PHONE_COUNT,mainCallPhoneFinal);
                                        String fzj = HttpClientUtils.getMethod("http://appweb.ihk.cn/ihkapp_web/app/cloudcall/get_browse_log_by_enrollnumber.htm?enrollNumber="+mainCallPhoneFinal);
                                        String zy = HttpClientUtils.getMethod("http://px.gd.hfit.ihk.cn/estate/cloudcall/cloudcallServlet.do?action_name=getPopupMsgByTel&tel="+mainCallPhoneFinal);
                                        JSONObject fzyJson = JSONObject.parseObject(fzj);
                                        JSONObject zyJson = JSONObject.parseObject(URLDecoder.decode(zy,"utf-8"));
                                        JSONObject obj = JSONObject.parseObject(contentFinal);
                                        obj.put("callCount",count);//回拨次数
                                        obj.put("interestedEstate",StringTools.isNotempty(fzyJson.get("data")) ? fzyJson.get("data") : ""); //感兴趣楼盘
                                        obj.put("propertyName",StringTools.isNotempty(zyJson.get("propertyName")) ? zyJson.get("propertyName") : "");//持有物业
                                        obj.put("projectName",StringTools.isNotempty(zyJson.get("projectName")) ? zyJson.get("projectName") : "");//已到过现场楼盘
                                        contentFinal = obj.toString();
                                        logger.debug("show window content:{}",contentFinal);
                                    }
                                    boolean flag = webSocketUtils.pushToChromeClientByUserId(zyId.toString(),contentFinal);
                                    logger.info("--------return webscoket flag--------[zyId:{},flag:{},mainCallPhone:{}]",zyId,flag,mainCallPhoneFinal);
                                } catch (UnsupportedEncodingException e) {
                                    logger.error("URLDecoder转换异常",e);
                                }
                            }
                        }.start();
                    }
                }
            } catch (Exception e) {
                logger.error("showWindowError",e);
            }
            //*****************返回弹屏数据****************//
        }
    }

    /**
     * 呼入通用记录参数
     * @param redisSaveMap
     * @param session
     * @param showNum 来显号码
     * @param mainCallPhone 主叫号码
     * @param targetCallPhone 被叫号码
     * @param userId 用户id
     * @param dataId
     * @param nowDateStr 状态时间
     * @param stateTime 创建时间
     * @param commitTo 提交到哪里
     * @param city  城市id
     * @param mainCallType 区别经纪或客户 主被叫关系
     * @param callType 通话类型
     * @param mainCallAnswered 主叫应答
     */
    private void addRedisSaveMap(Map<String,String> redisSaveMap,String session,String showNum,String mainCallPhone,
                                 String targetCallPhone,String userId,String dataId,String nowDateStr,String stateTime,
                                 String commitTo,String city,String mainCallType,String callType,String mainCallAnswered){
        redisSaveMap.put(RedisFields.CALL_HISTORY_SESSION_ID, session);
        redisSaveMap.put(RedisFields.CALL_HISTORY_SHOW_NUM, showNum);
        redisSaveMap.put(RedisFields.CALL_HISTORY_MAIN_CALL_PHONE, mainCallPhone);
        redisSaveMap.put(RedisFields.CALL_HISTORY_TARGET_CALL_PHONE, targetCallPhone);
        redisSaveMap.put(RedisFields.CREATE_USER_ID, userId);
        redisSaveMap.put(RedisFields.CALL_HISTORY_DATA_ID, dataId);
        redisSaveMap.put(RedisFields.RECEIVE_CALL_HISTORY_MAIN_CALL_ANSWERED, nowDateStr);
        redisSaveMap.put(RedisFields.CREATE_TIME, stateTime);
        redisSaveMap.put(RedisFields.CALL_HISTORY_MAIN_CALL_ANSWERED_TIME, stateTime);
        redisSaveMap.put(RedisFields.CALL_HISTORY_COMMIT_TO, commitTo);
        redisSaveMap.put(RedisFields.CALL_HISTORY_CITY, city);
        redisSaveMap.put(RedisFields.CALL_HISTORY_MAIN_CALL_TYPE, mainCallType);
        redisSaveMap.put(RedisFields.CALL_HISTORY_CALL_TYPE, callType);
        redisSaveMap.put(RedisFields.CALL_HISTORY_MAIN_CALL_ANSWERED, mainCallAnswered);

    }

    /**
     * app呼入通用记录参数
     * @param redisSaveMap
     * @param machineFrom 机器码
     * @param whereFrom 来源
     * @param pageFrom
     * @param customerName 客户姓名
     * @param commitTime 提交时间
     */
    private void addRedisSaveMap(Map<String,String> redisSaveMap,String machineFrom,String whereFrom,String pageFrom,String customerName,String commitTime){
        redisSaveMap.put(RedisFields.CALL_HISTORY_MACHINE_FROM,machineFrom);
        redisSaveMap.put(RedisFields.CALL_HISTORY_WHERE_FROM,whereFrom);
        redisSaveMap.put(RedisFields.CALL_HISTORY_PAGE_FROM,pageFrom);
        redisSaveMap.put(RedisFields.CALL_HISTORY_CUSTOMER_NAME,customerName);
        redisSaveMap.put(RedisFields.CALL_HISTORY_COMMIT_TIME, commitTime);
    }

    /**
     * 获取呼出线路
     * @param targetCallPhone
     */
    private void getFreeswitchLine(String targetCallPhone){


        logger.info(">>>>>>>>>>>>>>.开始进行外呼选线");
        String ccid = null;     //iccid
        String ip = null;       //本次外呼使用的设备ip
        String sipUser = null;  //本次外呼使用的设备的sip user
        String sn = null;       //本次外呼使用的设备ID
        String swxName = null;  //本次外呼使用的设备通道
        String phoneNum = null; //本次外呼使用的电话号码
        String snAndtrunkName = null;

        String queueName = RedisKey.DEFAULT_COMPANY+":"+RedisKey.DEFAULT_CITY  + RedisKey.SWX_CHANNEL_QUEUE;
        String queueMapName = RedisKey.DEFAULT_COMPANY+":"+RedisKey.DEFAULT_CITY  + RedisKey.SWX_CHANNEL_MAP;

        while (redisTemplate.opsForList().size(queueName) > 0) {
            Object queueValue = redisTemplate.opsForList().leftPop(queueName);

            if (queueValue == null) {//该队列没有值了返回告诉前端，没可用线路
                logger.info("外呼失败，当前没有可用线路");
                return;

            }
            snAndtrunkName = queueValue.toString();

            try{
                //出队以后删除对应的map
                redisTemplate.opsForHash().delete(queueMapName,snAndtrunkName);
            }catch (Exception e){
                logger.error(">>fs选线移除空闲线路异常!",e);
            }


            String[] arg = snAndtrunkName.split(":");
            if (arg.length < 2)
                break;

            sn = arg[0];
            swxName = arg[1];

            //判断当前取出的通道是否是空闲通道
            Map<String, String> trunkInfo = redisTemplate.opsForHash().entries(sn + ":" + swxName);

            if (trunkInfo == null || trunkInfo.size() == 0) //没有通道信息跳到下一个通道
                continue;

            String channelState = trunkInfo.get(RedisFields.STATE);
            String  equipmentState = trunkInfo.get(RedisFields.EQUIPMENT_STATE); //设备是否正常使用

            if (channelState == null || !"Idle".equals(channelState)||equipmentState==null||!"1".equals(equipmentState)) //当前通道不空闲 或者社保不可用，跳到下一个通道
                continue;

            ip = trunkInfo.get(RedisFields.IP);
            sipUser = trunkInfo.get(RedisFields.FS_SIP_USER);
            phoneNum = trunkInfo.get(RedisFields.PHONE_NUM);
            ccid = trunkInfo.get(RedisFields.ICCID);
            break;
        }

        if (sipUser == null || ccid == null || swxName == null) {
            logger.info("外呼失败，当前没有可用线路");
            return;
        }

        logger.info(">>fs呼出选线结果：sn：{}，swxName：{}，ip：{}，sipUser：{}，phoneNum：{}，ccid：{}",
                sn, swxName, ip, sipUser, phoneNum, ccid);

        String suffixSipUser = sipUser.substring((sipUser.length() - 2), sipUser.length());
        String suffixSwx = swxName.substring(3, swxName.length()).length() > 1 ? swxName.substring(3, swxName.length()) : "0" + swxName.substring(3, swxName.length());

        logger.info(">>fs呼出选线结果，前缀：suffixSipUser：{}，suffixSwx：{}",
                suffixSipUser, suffixSwx);
        targetCallPhone  = "199"+suffixSipUser+suffixSwx+targetCallPhone;
    }
}
